/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2002-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_defs.h"

#if defined (UMC_ENABLE_AC3_AUDIO_DECODER)

#include "ac3_dec.h"
#include "ac3_dec_own_fp.h"

/********************************************************************/

#define DITHMULT  47989
#define DITHER_GEN(x)                                                      \
{                                                                          \
  Ipp32s tmp0, tmp1;                                                       \
  tmp0 = (((Ipp32s)(DITHMULT * state->mants_tabls.dithtemp)) << 16) >> 16; \
  state->mants_tabls.dithtemp = (Ipp16s)tmp0;                              \
  tmp1 = (((Ipp32s)(DITHMULT * state->mants_tabls.dithtemp)) << 16) >> 16; \
  state->mants_tabls.dithtemp = (Ipp16s)tmp1;                              \
  x = (0.707106781f * 0.5f * (tmp0 + tmp1));                               \
}

/********************************************************************/

void uncoupleChannel(AC3Dec *state,
                     Ipp32s ch);

static Ipp32f q_1[32][3] = /* bap=1 (3-Level) Quantization */
{
  {-65536.0f/3.0f, -65536.0f/3.0f, -65536.0f/3.0f},
  {-65536.0f/3.0f, -65536.0f/3.0f,              0},
  {-65536.0f/3.0f, -65536.0f/3.0f,  65536.0f/3.0f},
  {-65536.0f/3.0f,              0, -65536.0f/3.0f},
  {-65536.0f/3.0f,              0,              0},
  {-65536.0f/3.0f,              0,  65536.0f/3.0f},
  {-65536.0f/3.0f,  65536.0f/3.0f, -65536.0f/3.0f},
  {-65536.0f/3.0f,  65536.0f/3.0f,              0},
  {-65536.0f/3.0f,  65536.0f/3.0f,  65536.0f/3.0f},
  {             0, -65536.0f/3.0f, -65536.0f/3.0f},
  {             0, -65536.0f/3.0f,              0},
  {             0, -65536.0f/3.0f,  65536.0f/3.0f},
  {             0,              0, -65536.0f/3.0f},
  {             0,              0,              0},
  {             0,              0,  65536.0f/3.0f},
  {             0,  65536.0f/3.0f, -65536.0f/3.0f},
  {             0,  65536.0f/3.0f,              0},
  {             0,  65536.0f/3.0f,  65536.0f/3.0f},
  { 65536.0f/3.0f, -65536.0f/3.0f, -65536.0f/3.0f},
  { 65536.0f/3.0f, -65536.0f/3.0f,              0},
  { 65536.0f/3.0f, -65536.0f/3.0f,  65536.0f/3.0f},
  { 65536.0f/3.0f,              0, -65536.0f/3.0f},
  { 65536.0f/3.0f,              0,              0},
  { 65536.0f/3.0f,              0,  65536.0f/3.0f},
  { 65536.0f/3.0f,  65536.0f/3.0f, -65536.0f/3.0f},
  { 65536.0f/3.0f,  65536.0f/3.0f,              0},
  { 65536.0f/3.0f,  65536.0f/3.0f,  65536.0f/3.0f},
  {             0,              0,              0},
  {             0,              0,              0},
  {             0,              0,              0},
  {             0,              0,              0}
};

static Ipp32f q_2[128][3] = /* bap=2 (5-Level) Quantization */
{
  {-131072.0f / 5, -131072.0f / 5, -131072.0f / 5},
  {-131072.0f / 5, -131072.0f / 5,  -65536.0f / 5},
  {-131072.0f / 5, -131072.0f / 5,              0},
  {-131072.0f / 5, -131072.0f / 5,   65536.0f / 5},
  {-131072.0f / 5, -131072.0f / 5,  131072.0f / 5},
  {-131072.0f / 5,  -65536.0f / 5, -131072.0f / 5},
  {-131072.0f / 5,  -65536.0f / 5,  -65536.0f / 5},
  {-131072.0f / 5,  -65536.0f / 5,              0},
  {-131072.0f / 5,  -65536.0f / 5,   65536.0f / 5},
  {-131072.0f / 5,  -65536.0f / 5,  131072.0f / 5},
  {-131072.0f / 5,              0, -131072.0f / 5},
  {-131072.0f / 5,              0,  -65536.0f / 5},
  {-131072.0f / 5,              0,              0},
  {-131072.0f / 5,              0,   65536.0f / 5},
  {-131072.0f / 5,              0,  131072.0f / 5},
  {-131072.0f / 5,   65536.0f / 5, -131072.0f / 5},
  {-131072.0f / 5,   65536.0f / 5,  -65536.0f / 5},
  {-131072.0f / 5,   65536.0f / 5,              0},
  {-131072.0f / 5,   65536.0f / 5,   65536.0f / 5},
  {-131072.0f / 5,   65536.0f / 5,  131072.0f / 5},
  {-131072.0f / 5,  131072.0f / 5, -131072.0f / 5},
  {-131072.0f / 5,  131072.0f / 5,  -65536.0f / 5},
  {-131072.0f / 5,  131072.0f / 5,              0},
  {-131072.0f / 5,  131072.0f / 5,   65536.0f / 5},
  {-131072.0f / 5,  131072.0f / 5,  131072.0f / 5},
  { -65536.0f / 5, -131072.0f / 5, -131072.0f / 5},
  { -65536.0f / 5, -131072.0f / 5,  -65536.0f / 5},
  { -65536.0f / 5, -131072.0f / 5,              0},
  { -65536.0f / 5, -131072.0f / 5,   65536.0f / 5},
  { -65536.0f / 5, -131072.0f / 5,  131072.0f / 5},
  { -65536.0f / 5,  -65536.0f / 5, -131072.0f / 5},
  { -65536.0f / 5,  -65536.0f / 5,  -65536.0f / 5},
  { -65536.0f / 5,  -65536.0f / 5,              0},
  { -65536.0f / 5,  -65536.0f / 5,   65536.0f / 5},
  { -65536.0f / 5,  -65536.0f / 5,  131072.0f / 5},
  { -65536.0f / 5,              0, -131072.0f / 5},
  { -65536.0f / 5,              0,  -65536.0f / 5},
  { -65536.0f / 5,              0,              0},
  { -65536.0f / 5,              0,   65536.0f / 5},
  { -65536.0f / 5,              0,  131072.0f / 5},
  { -65536.0f / 5,   65536.0f / 5, -131072.0f / 5},
  { -65536.0f / 5,   65536.0f / 5,  -65536.0f / 5},
  { -65536.0f / 5,   65536.0f / 5,              0},
  { -65536.0f / 5,   65536.0f / 5,   65536.0f / 5},
  { -65536.0f / 5,   65536.0f / 5,  131072.0f / 5},
  { -65536.0f / 5,  131072.0f / 5, -131072.0f / 5},
  { -65536.0f / 5,  131072.0f / 5,  -65536.0f / 5},
  { -65536.0f / 5,  131072.0f / 5,              0},
  { -65536.0f / 5,  131072.0f / 5,   65536.0f / 5},
  { -65536.0f / 5,  131072.0f / 5,  131072.0f / 5},
  {             0, -131072.0f / 5, -131072.0f / 5},
  {             0, -131072.0f / 5,  -65536.0f / 5},
  {             0, -131072.0f / 5,              0},
  {             0, -131072.0f / 5,   65536.0f / 5},
  {             0, -131072.0f / 5,  131072.0f / 5},
  {             0,  -65536.0f / 5, -131072.0f / 5},
  {             0,  -65536.0f / 5,  -65536.0f / 5},
  {             0,  -65536.0f / 5,              0},
  {             0,  -65536.0f / 5,   65536.0f / 5},
  {             0,  -65536.0f / 5,  131072.0f / 5},
  {             0,              0, -131072.0f / 5},
  {             0,              0,  -65536.0f / 5},
  {             0,              0,              0},
  {             0,              0,   65536.0f / 5},
  {             0,              0,  131072.0f / 5},
  {             0,   65536.0f / 5, -131072.0f / 5},
  {             0,   65536.0f / 5,  -65536.0f / 5},
  {             0,   65536.0f / 5,              0},
  {             0,   65536.0f / 5,   65536.0f / 5},
  {             0,   65536.0f / 5,  131072.0f / 5},
  {             0,  131072.0f / 5, -131072.0f / 5},
  {             0,  131072.0f / 5,  -65536.0f / 5},
  {             0,  131072.0f / 5,              0},
  {             0,  131072.0f / 5,   65536.0f / 5},
  {             0,  131072.0f / 5,  131072.0f / 5},
  {  65536.0f / 5, -131072.0f / 5, -131072.0f / 5},
  {  65536.0f / 5, -131072.0f / 5,  -65536.0f / 5},
  {  65536.0f / 5, -131072.0f / 5,              0},
  {  65536.0f / 5, -131072.0f / 5,   65536.0f / 5},
  {  65536.0f / 5, -131072.0f / 5,  131072.0f / 5},
  {  65536.0f / 5,  -65536.0f / 5, -131072.0f / 5},
  {  65536.0f / 5,  -65536.0f / 5,  -65536.0f / 5},
  {  65536.0f / 5,  -65536.0f / 5,              0},
  {  65536.0f / 5,  -65536.0f / 5,   65536.0f / 5},
  {  65536.0f / 5,  -65536.0f / 5,  131072.0f / 5},
  {  65536.0f / 5,              0, -131072.0f / 5},
  {  65536.0f / 5,              0,  -65536.0f / 5},
  {  65536.0f / 5,              0,              0},
  {  65536.0f / 5,              0,   65536.0f / 5},
  {  65536.0f / 5,              0,  131072.0f / 5},
  {  65536.0f / 5,   65536.0f / 5, -131072.0f / 5},
  {  65536.0f / 5,   65536.0f / 5,  -65536.0f / 5},
  {  65536.0f / 5,   65536.0f / 5,              0},
  {  65536.0f / 5,   65536.0f / 5,   65536.0f / 5},
  {  65536.0f / 5,   65536.0f / 5,  131072.0f / 5},
  {  65536.0f / 5,  131072.0f / 5, -131072.0f / 5},
  {  65536.0f / 5,  131072.0f / 5,  -65536.0f / 5},
  {  65536.0f / 5,  131072.0f / 5,              0},
  {  65536.0f / 5,  131072.0f / 5,   65536.0f / 5},
  {  65536.0f / 5,  131072.0f / 5,  131072.0f / 5},
  { 131072.0f / 5, -131072.0f / 5, -131072.0f / 5},
  { 131072.0f / 5, -131072.0f / 5,  -65536.0f / 5},
  { 131072.0f / 5, -131072.0f / 5,              0},
  { 131072.0f / 5, -131072.0f / 5,   65536.0f / 5},
  { 131072.0f / 5, -131072.0f / 5,  131072.0f / 5},
  { 131072.0f / 5,  -65536.0f / 5, -131072.0f / 5},
  { 131072.0f / 5,  -65536.0f / 5,  -65536.0f / 5},
  { 131072.0f / 5,  -65536.0f / 5,              0},
  { 131072.0f / 5,  -65536.0f / 5,   65536.0f / 5},
  { 131072.0f / 5,  -65536.0f / 5,  131072.0f / 5},
  { 131072.0f / 5,              0, -131072.0f / 5},
  { 131072.0f / 5,              0,  -65536.0f / 5},
  { 131072.0f / 5,              0,              0},
  { 131072.0f / 5,              0,   65536.0f / 5},
  { 131072.0f / 5,              0,  131072.0f / 5},
  { 131072.0f / 5,   65536.0f / 5, -131072.0f / 5},
  { 131072.0f / 5,   65536.0f / 5,  -65536.0f / 5},
  { 131072.0f / 5,   65536.0f / 5,              0},
  { 131072.0f / 5,   65536.0f / 5,   65536.0f / 5},
  { 131072.0f / 5,   65536.0f / 5,  131072.0f / 5},
  { 131072.0f / 5,  131072.0f / 5, -131072.0f / 5},
  { 131072.0f / 5,  131072.0f / 5,  -65536.0f / 5},
  { 131072.0f / 5,  131072.0f / 5,              0},
  { 131072.0f / 5,  131072.0f / 5,   65536.0f / 5},
  { 131072.0f / 5,  131072.0f / 5,  131072.0f / 5},
  {             0,              0,              0},
  {             0,              0,              0},
  {             0,              0,              0}
};

static Ipp32f q_3[8] =   /* bap=3 (7-Level) Quantization */
{
  -196608.0f / 7, -131072.0f / 7, -65536.0f / 7, 0,
    65536.0f / 7,  131072.0f / 7, 196608.0f / 7, 0
};

static Ipp32f q_4[128][2] = /* bap=4 (11-Level) Quantization */
{
  {-327680.0f / 11, -327680.0f / 11},
  {-327680.0f / 11, -262144.0f / 11},
  {-327680.0f / 11, -196608.0f / 11},
  {-327680.0f / 11, -131072.0f / 11},
  {-327680.0f / 11,  -65536.0f / 11},
  {-327680.0f / 11,               0},
  {-327680.0f / 11,   65536.0f / 11},
  {-327680.0f / 11,  131072.0f / 11},
  {-327680.0f / 11,  196608.0f / 11},
  {-327680.0f / 11,  262144.0f / 11},
  {-327680.0f / 11,  327680.0f / 11},
  {-262144.0f / 11, -327680.0f / 11},
  {-262144.0f / 11, -262144.0f / 11},
  {-262144.0f / 11, -196608.0f / 11},
  {-262144.0f / 11, -131072.0f / 11},
  {-262144.0f / 11,  -65536.0f / 11},
  {-262144.0f / 11,               0},
  {-262144.0f / 11,   65536.0f / 11},
  {-262144.0f / 11,  131072.0f / 11},
  {-262144.0f / 11,  196608.0f / 11},
  {-262144.0f / 11,  262144.0f / 11},
  {-262144.0f / 11,  327680.0f / 11},
  {-196608.0f / 11, -327680.0f / 11},
  {-196608.0f / 11, -262144.0f / 11},
  {-196608.0f / 11, -196608.0f / 11},
  {-196608.0f / 11, -131072.0f / 11},
  {-196608.0f / 11,  -65536.0f / 11},
  {-196608.0f / 11,               0},
  {-196608.0f / 11,   65536.0f / 11},
  {-196608.0f / 11,  131072.0f / 11},
  {-196608.0f / 11,  196608.0f / 11},
  {-196608.0f / 11,  262144.0f / 11},
  {-196608.0f / 11,  327680.0f / 11},
  {-131072.0f / 11, -327680.0f / 11},
  {-131072.0f / 11, -262144.0f / 11},
  {-131072.0f / 11, -196608.0f / 11},
  {-131072.0f / 11, -131072.0f / 11},
  {-131072.0f / 11,  -65536.0f / 11},
  {-131072.0f / 11,               0},
  {-131072.0f / 11,   65536.0f / 11},
  {-131072.0f / 11,  131072.0f / 11},
  {-131072.0f / 11,  196608.0f / 11},
  {-131072.0f / 11,  262144.0f / 11},
  {-131072.0f / 11,  327680.0f / 11},
  { -65536.0f / 11, -327680.0f / 11},
  { -65536.0f / 11, -262144.0f / 11},
  { -65536.0f / 11, -196608.0f / 11},
  { -65536.0f / 11, -131072.0f / 11},
  { -65536.0f / 11,  -65536.0f / 11},
  { -65536.0f / 11,               0},
  { -65536.0f / 11,   65536.0f / 11},
  { -65536.0f / 11,  131072.0f / 11},
  { -65536.0f / 11,  196608.0f / 11},
  { -65536.0f / 11,  262144.0f / 11},
  { -65536.0f / 11,  327680.0f / 11},
  {              0, -327680.0f / 11},
  {              0, -262144.0f / 11},
  {              0, -196608.0f / 11},
  {              0, -131072.0f / 11},
  {              0,  -65536.0f / 11},
  {              0,               0},
  {              0,   65536.0f / 11},
  {              0,  131072.0f / 11},
  {              0,  196608.0f / 11},
  {              0,  262144.0f / 11},
  {              0,  327680.0f / 11},
  {  65536.0f / 11, -327680.0f / 11},
  {  65536.0f / 11, -262144.0f / 11},
  {  65536.0f / 11, -196608.0f / 11},
  {  65536.0f / 11, -131072.0f / 11},
  {  65536.0f / 11,  -65536.0f / 11},
  {  65536.0f / 11,               0},
  {  65536.0f / 11,   65536.0f / 11},
  {  65536.0f / 11,  131072.0f / 11},
  {  65536.0f / 11,  196608.0f / 11},
  {  65536.0f / 11,  262144.0f / 11},
  {  65536.0f / 11,  327680.0f / 11},
  { 131072.0f / 11, -327680.0f / 11},
  { 131072.0f / 11, -262144.0f / 11},
  { 131072.0f / 11, -196608.0f / 11},
  { 131072.0f / 11, -131072.0f / 11},
  { 131072.0f / 11,  -65536.0f / 11},
  { 131072.0f / 11,               0},
  { 131072.0f / 11,   65536.0f / 11},
  { 131072.0f / 11,  131072.0f / 11},
  { 131072.0f / 11,  196608.0f / 11},
  { 131072.0f / 11,  262144.0f / 11},
  { 131072.0f / 11,  327680.0f / 11},
  { 196608.0f / 11, -327680.0f / 11},
  { 196608.0f / 11, -262144.0f / 11},
  { 196608.0f / 11, -196608.0f / 11},
  { 196608.0f / 11, -131072.0f / 11},
  { 196608.0f / 11,  -65536.0f / 11},
  { 196608.0f / 11,               0},
  { 196608.0f / 11,   65536.0f / 11},
  { 196608.0f / 11,  131072.0f / 11},
  { 196608.0f / 11,  196608.0f / 11},
  { 196608.0f / 11,  262144.0f / 11},
  { 196608.0f / 11,  327680.0f / 11},
  { 262144.0f / 11, -327680.0f / 11},
  { 262144.0f / 11, -262144.0f / 11},
  { 262144.0f / 11, -196608.0f / 11},
  { 262144.0f / 11, -131072.0f / 11},
  { 262144.0f / 11,  -65536.0f / 11},
  { 262144.0f / 11,               0},
  { 262144.0f / 11,   65536.0f / 11},
  { 262144.0f / 11,  131072.0f / 11},
  { 262144.0f / 11,  196608.0f / 11},
  { 262144.0f / 11,  262144.0f / 11},
  { 262144.0f / 11,  327680.0f / 11},
  { 327680.0f / 11, -327680.0f / 11},
  { 327680.0f / 11, -262144.0f / 11},
  { 327680.0f / 11, -196608.0f / 11},
  { 327680.0f / 11, -131072.0f / 11},
  { 327680.0f / 11,  -65536.0f / 11},
  { 327680.0f / 11,               0},
  { 327680.0f / 11,   65536.0f / 11},
  { 327680.0f / 11,  131072.0f / 11},
  { 327680.0f / 11,  196608.0f / 11},
  { 327680.0f / 11,  262144.0f / 11},
  { 327680.0f / 11,  327680.0f / 11},
  {              0,               0},
  {              0,               0},
  {              0,               0},
  {              0,               0},
  {              0,               0},
  {              0,               0},
  {              0,               0}
};

static Ipp32f q_5[16] =  /* bap=5 (15-Level) Quantization */
{
  -458752.0f / 15, -393216.0f / 15, -327680.0f / 15, -262144.0f / 15,
  -196608.0f / 15, -131072.0f / 15,  -65536.0f / 15,               0,
    65536.0f / 15,  131072.0f / 15,  196608.0f / 15,  262144.0f / 15,
   327680.0f / 15,  393216.0f / 15,  458752.0f / 15, 0
};

/* Conversion from bap to number of bits in the mantissas */
/* zeros account for cases 0,1,2,4 which are special cased */
static Ipp32s  QNTTZTAB[16] =
{ 0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 };

//#if (defined (__GNUC__) && defined(LINUX64))
#if defined (__GNUC__)
static float MakeFloat_gcc4_32f(Ipp32f inmant,
                                Ipp32s inexp)
{
  inmant *= 0.000030517578125f;
  if (inexp >= 0) {
    while (inexp >= 30) {
      inmant *= 0.000000000931322574615478515625f;
      inexp -= 30;
    }
    inmant /= (Ipp32f)(1 << inexp);
  } else {
    inexp = -inexp;
    while (inexp >= 30) {
      inmant *= 1073741824.0f;
      inexp -= 30;
    }
    inmant *= (Ipp32f)(1 << inexp);
  }
  return inmant;
}

#endif

/********************************************************************/

static void MakeFloat_32f(Ipp32f *inmant,
                          Ipp32s *inexp,
                          Ipp32s size,
                          Ipp32f *outfloat)
{
  Ipp32s  i;
  Ipp32s  bias;
  Ipp32f  tmp;

  for (i = 0; i < size; i++) {
//#if (defined (__GNUC__) && defined(LINUX64))
#if defined (__GNUC__)
    outfloat[i] = MakeFloat_gcc4_32f(inmant[i], inexp[i]);
#else
    bias = 112 - (Ipp32s)inexp[i];
    bias = bias << 23;
    bias = bias & 0x7FFFFFFF;
    *(Ipp32s*)(&tmp) = bias;
    outfloat[i] = inmant[i]*tmp;
#endif
  }
}

/********************************************************************/

static Ipp32s getMantissas(Ipp32s *bap,
                           Ipp32s do_dither,
                           Ipp32f *mant,
                           Ipp32s count,
                           AC3Dec *state,
                           sBitsreamBuffer *pBS)
{
  Ipp32s index;
  Ipp32s tmp, i;
  Ipp32s m_1_pointer, m_2_pointer, m_4_pointer;
  Ipp32f *fast_m_1, *fast_m_2, *fast_m_4;

  m_1_pointer = state->mants_tabls.m_1_pointer;
  m_2_pointer = state->mants_tabls.m_2_pointer;
  m_4_pointer = state->mants_tabls.m_4_pointer;

  fast_m_1 = state->mants_tabls.fast_m_1;
  fast_m_2 = state->mants_tabls.fast_m_2;
  fast_m_4 = state->mants_tabls.fast_m_4;

  for (i = 0; i < count; i++) {
    switch (bap[i]) {
    case 0:
      if (do_dither) {
        DITHER_GEN(mant[i]);
      } else {
        mant[i] = 0;
      }
      break;
    case 1:
      if (m_1_pointer > 2) {
        GET_BITS(pBS, index, 5, Ipp32s)
        fast_m_1 = q_1[index];
        m_1_pointer = 0;
      }
      mant[i] = fast_m_1[m_1_pointer];
      m_1_pointer++;
      break;
    case 2:
      if (m_2_pointer > 2) {
        GET_BITS(pBS, index, 7, Ipp32s)
        fast_m_2 = q_2[index];
        m_2_pointer = 0;
      }
      mant[i] = fast_m_2[m_2_pointer];
      m_2_pointer++;
      break;

    case 3:
      GET_BITS(pBS, index, 3, Ipp32s)
      mant[i] = q_3[index];
      break;

    case 4:
      if (m_4_pointer > 1) {
        GET_BITS(pBS, index, 7, Ipp32s)
        fast_m_4 = q_4[index];
        m_4_pointer = 0;
      }
      mant[i] = fast_m_4[m_4_pointer];
      m_4_pointer++;
      break;

    case 5:
      GET_BITS(pBS, index, 4, Ipp32s)
      mant[i] = q_5[index];
      break;

    default:
      index = QNTTZTAB[bap[i]];
      GET_BITS(pBS, tmp, index, Ipp32s)
      tmp <<= (32 - index);
      mant[i] = (Ipp32f)(tmp >>16);
    }
  }

  state->mants_tabls.m_1_pointer = m_1_pointer;
  state->mants_tabls.m_2_pointer = m_2_pointer;
  state->mants_tabls.m_4_pointer = m_4_pointer;

  state->mants_tabls.fast_m_1 = fast_m_1;
  state->mants_tabls.fast_m_2 = fast_m_2;
  state->mants_tabls.fast_m_4 = fast_m_4;

  return 1;
}

/********************************************************************/

Ipp32s UnpackMantissas(AC3Dec *state,
                       sBitsreamBuffer *pBS)
{
  Ipp32s i, j;
  Ipp32s done_cpl = 0;
  Ipp32f *mant_ptr;
  Ipp32s *bap_ptr;
  Ipp32s *exp_ptr;
  Ipp32s do_dither = 0;
  Ipp32s do_dither_prev = 0;
  Ipp32s count;
  _AudBlk *audblk = &(state->audblk);

  state->mants_tabls.m_1_pointer =
  state->mants_tabls.m_2_pointer =
  state->mants_tabls.m_4_pointer = 3;

  for (i = 0; i < state->bsi.nfchans; i++) {
    mant_ptr = state->fbw_mant[i];
    bap_ptr = state->fbw_bap[i];
    do_dither = ((audblk->dithflag >> (state->bsi.nfchans - i - 1)) & 1);

    getMantissas(bap_ptr, do_dither, mant_ptr,
                 audblk->endmant[i], state, pBS);

    MakeFloat_32f(state->fbw_mant[i],
                  state->fbw_exp[i],
                  audblk->endmant[i],
                  &(state->coeffs[i][0]));

    ippsZero_32f(&(state->coeffs[i][audblk->endmant[i]]),
                 256 - audblk->endmant[i]);

    if (audblk->cplinu && audblk->chincpl[i]) {
      j = audblk->cplstrtmant;
      mant_ptr = &(state->cpl_mant[j]);
      bap_ptr = &(state->cpl_bap[j]);
      exp_ptr = &(state->cpl_exp[j]);
      count = audblk->cplendmant - audblk->cplstrtmant;

      if (!done_cpl) {
        getMantissas(bap_ptr, do_dither, mant_ptr, count, state, pBS);
        MakeFloat_32f(mant_ptr, exp_ptr, count,
                      &(state->cplChannel[j]));
      } else if (do_dither) {
        Ipp32s ii;

        for (ii = 0; ii < count; ii++) {
          if (bap_ptr[ii] == 0) {
            Ipp32f tmp;

            DITHER_GEN(mant_ptr[ii]);

#if (defined (__GNUC__) && defined(LINUX64))
            state->cplChannel[j + ii] = MakeFloat_gcc4_32f(mant_ptr[ii], exp_ptr[ii]);
#else
            *(Ipp32s*)(&tmp) = (((112 - (Ipp32s)exp_ptr[ii]) << 23) & 0x7FFFFFFF);
            state->cplChannel[j + ii] = (Ipp32f)mant_ptr[ii] * tmp;
#endif

          }
        }
      } else if (do_dither_prev) {
        Ipp32s ii;

        for (ii = 0; ii < count; ii++) {
          if (bap_ptr[ii] == 0) {
            state->cplChannel[j + ii] = 0;
          }
        }
      }

      uncoupleChannel(state, i);
      done_cpl = 1;
      do_dither_prev = do_dither;
    }
  }

  if (state->bsi.lfeon) {
    /* There are always 7 mantissas for lfe */
    getMantissas(state->lfe_bap, 0, state->lfe_mant, 7, state, pBS);
    if (state->outlfeon) {
      MakeFloat_32f(state->lfe_mant, state->lfe_exp, 7,
                    &(state->coeffs[5][0]));
    }
  }

  return 1;
}

/********************************************************************/

#endif //UMC_ENABLE_AC3_AUDIO_DECODER


